#pragma once

#include "StickyTweetsStatus.h"
#include "Settings.h"

/*!
 * \brief An interface that defines our application
 */
class IStickyTweetsApp
{
public:
  /*!
   * \brief   Return the string version of this build
   *
   * If there is an error, return an empty string.
   */
  virtual CString GetVersion(VOID) = 0;

  /*!
   * \brief   Extract the user's saved settings
   *
   * Should be called only once, during startup unless you're reloading.
   */
  virtual StickyTweetsStatus LoadSettings(bool reload) = 0;

  /*!
   * \brief   Save the user's settings
   *
   * This will overwrite ALL settings.
   */
  virtual StickyTweetsStatus SaveSettings(const Settings& settings) = 0;

  /*!
   * \brief   No matter what, return some settings
   */
  virtual Settings GetSettings(VOID) = 0;

  /*!
   * \brief   Get known screen names from registry
   */
  virtual void GetScreenNames(CAtlList<CString>& list) = 0;

  /*!
   * \brief   Format and store the system error message
   */
  virtual StickyTweetsStatus SetSystemError(LONG errorCode) = 0;

  /*!
   * \brief   Retrieve the last stored system error
   */
  virtual CString GetSystemError(VOID) = 0;

  /*!
   * \brief   Extract and store the message from XML returned by Twitter
   */
  virtual StickyTweetsStatus SetTwitterError(const CString& errorXml) = 0;

  /*!
   * \brief   Retrieve the last stored Twitter error
   */
  virtual CString GetTwitterError(VOID) = 0;

  /*!
   * \brief   Ask Twitter to verify credentials
   */
  virtual StickyTweetsStatus VerifyCredentials(const TCHAR* screenName, const TCHAR* password) = 0;

  /*!
   * \brief   Get the XML for the user's current friends timeline
   * \param   sinceId - Return tweets since this optional tweet ID
   */
  virtual StickyTweetsStatus GetCurrentTimelineXml(CString& xml, CString sinceId = L"") = 0;

  /*!
   * \brief   Get the Twitter XML a single user
   */
  virtual StickyTweetsStatus GetUserTimelineXml(const CString& screenName, CString& xml) = 0;

  /*!
   * \brief   Search Twitter
   *
   * Return the search results as Atom XML.
   */
  virtual StickyTweetsStatus GetSearchAtom(const CString& query, CString& atomXml) = 0;

  /*!
   * \brief   Return TRUE if the logged in user is following the passed in screen name
   */
  virtual BOOL IsFollowing(const CString& screenName) = 0;

  /*!
   * \brief   Download an image from the Interwebs
   *
   * This method should intentionally use Wininet's caching for faster response.
   */
  virtual StickyTweetsStatus DownloadImage(const CString& imageUrl, Image** image) = 0;

  /*!
   * \brief   Update the user's status, return true if ok
   */
  virtual StickyTweetsStatus UpdateStatus(const CString& status, const CString& inReplyToId) = 0;

  /*!
   * \brief   Send a direct message to a user
   */
  virtual StickyTweetsStatus SendDm(const CString& user, const CString& text) = 0;

  /*!
   * \brief   Follow or un-follow a user
   */
  virtual StickyTweetsStatus Follow(const CString& screenName, BOOL follow) = 0;

  /*!
   * \brief   Tr.im a URL
   *
   * This message should return StatusStOk almost always actually, even if we return the same URL.
   */
  virtual StickyTweetsStatus TrimUrl(const CString& original, CString& trimmed) = 0;
  
  /*!
   * \brief   Return TRUE if url is already from one of the known URL shrinking websites
   */
  virtual BOOL IsTrimmed(const CString& url) = 0;

  /*!
   * \brief   Encode a URI component
   */
  virtual CString EncodeUri(const CString& uri) = 0;

  /*!
   * \brief   Make a UTF date look a lot nicer
   * \param   date - Can be Twitter date format or Atom date format
   * \return  Pretty date or argument if formatting fails
   *
   * If we find a space in the string, attempt to format a Twitter date.
   * If we don't, attempt to format an Atom (search result) date.
   */
  virtual CString FormatDate(const CString& date) = 0;
};
